package com.yswee.framework.widget.loading;

import com.yswee.framework.activity.IActivityContext;
import com.yswee.framework.manager.ActivityManager;
import com.yswee.framework.utils.ViewInjectUtils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

public class LoadingLayout extends RelativeLayout {

	public static final int NOTSET = 0;
	public static final int INITIALIZED = 1;
	public static final int LOADING = 2;
	public static final int SUCCESSFUL = 4;
	public static final int ERROR = 5;
	
	protected View BlankView;
	protected View LoadingView;
	protected View ErrorView;
	protected View ContentView;
	
	public int getStatus() {
		return mStatus;
	}

	private boolean initializing;
	
	protected int mStatus = NOTSET;
	protected Context mContext;
	
	protected boolean getAutoLoading() {
		return true;
	}
	
	protected boolean getRetryOnError() {
		return true;
	}

	public LoadingLayout(Context context) {
		super(context);
		initializeLayout(context);
	}
	
	public LoadingLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		initializeLayout(context);
	}
	
	public LoadingLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initializeLayout(context);
	}
	
	protected void initializeLayout(Context context) {
		mContext = context;
		setContentView();
		onInjectView();
		onFindView();
		onBindListener();
		onApplyData();
		mStatus = INITIALIZED;
	}
	
	protected void setContentView() {
		initializing = true;
		int contentResId = getLayoutResId();
		if(contentResId != 0) {
			ContentView = LayoutInflater.from(mContext).inflate(contentResId, null, false);
		}
		if(ContentView == null) {
			ContentView = getLayoutView();
		}
		if(ContentView == null) {
			ContentView = new RelativeLayout(mContext);
		}
		ContentView.setId(generateViewId());
		addView(ContentView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		int blankResId = getBlankResId();
		if(blankResId != 0) {
			BlankView = LayoutInflater.from(mContext).inflate(blankResId, null, false);
		}
		if(BlankView == null) {
			BlankView = getBlankView();
		}
		if(BlankView != null) {
			LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			params.addRule(RelativeLayout.ALIGN_LEFT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_RIGHT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_TOP, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_BOTTOM, ContentView.getId());
			addView(BlankView, params);
			BlankView.setVisibility(View.GONE);
		}
		int errResId = getErrorResId();
		if(errResId != 0) {
			ErrorView = LayoutInflater.from(mContext).inflate(errResId, null, false);
		}
		if(ErrorView == null) {
			ErrorView = getErrorView();
		}
		if(ErrorView != null) {
			LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			params.addRule(RelativeLayout.ALIGN_LEFT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_RIGHT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_TOP, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_BOTTOM, ContentView.getId());
			addView(ErrorView, params);
			ErrorView.setVisibility(View.GONE);
		}
		int loadingResId = getLoadingResId();
		if(loadingResId != 0) {
			LoadingView = LayoutInflater.from(mContext).inflate(loadingResId, null, false);
		}
		if(LoadingView == null) {
			LoadingView = getLoadingView();
		}
		if(LoadingView != null) {
			LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			params.addRule(RelativeLayout.ALIGN_LEFT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_RIGHT, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_TOP, ContentView.getId());
			params.addRule(RelativeLayout.ALIGN_BOTTOM, ContentView.getId());
			addView(LoadingView, params);
			LoadingView.setVisibility(View.GONE);
		} else {
			throw new IllegalStateException("you should override getLoadingResId or getLoadingView method");
		}
		initializing = false;
	}
	
	/**
	 * 初始化控件、获取内部控件（注释类遍历）
	 */
	protected void onInjectView() {
		ViewInjectUtils.onInjectView(this);
	}
	
	/**
	 * 初始化控件、获取内部控件
	 */
	protected void onFindView() {
		
	}
	
	protected void onBindListener() {
		if(BlankView != null) {
			BlankView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					onApplyLoadingData();
				}
			});
		}
		if(ErrorView != null) {
			ErrorView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					onApplyLoadingData();
				}
			});
		}
	}
	
	/**
	 * 加载数据
	 */
	protected void onApplyData() {
		
	}
	
	@Override
	public void addView(View child, int index,
			android.view.ViewGroup.LayoutParams params) {
		// 不加载其他控件
		if(initializing) {
			super.addView(child, index, params);
		} else {
			if(ContentView instanceof ViewGroup) {
				((ViewGroup) ContentView).addView(child, index, params);
			}
		}
	}
	
	@Override
	protected boolean addViewInLayout(View child, int index,
			android.view.ViewGroup.LayoutParams params,
			boolean preventRequestLayout) {
		// 不加载其他控件
		if(initializing) {
			return super.addViewInLayout(child, index, params, preventRequestLayout);
		}
		return false;
	}
	
	/**
	 * 显示loading时是否隐藏contentview
	 * @return
	 */
	protected boolean hideContentOnAction() {
		return true;
	}
	
	/**
	 * 切换至加载空白状态
	 */
	public void gotoBlank() {
		if(LoadingView != null)
			LoadingView.setVisibility(View.GONE);
		if(ContentView != null)
			ContentView.setVisibility(View.INVISIBLE);
		if(ErrorView != null)
			ErrorView.setVisibility(View.GONE);
		if(BlankView != null)
			BlankView.setVisibility(View.VISIBLE);
		mStatus = SUCCESSFUL;
	}

	/**
	 * 切换至加载中状态
	 */
	public void gotoLoading() {
		if(mStatus == LOADING)
			return;
		if(ContentView != null)
			ContentView.setVisibility(hideContentOnAction() ? View.INVISIBLE : View.VISIBLE);
		if(BlankView != null)
			BlankView.setVisibility(View.GONE);
		if(ErrorView != null)
			ErrorView.setVisibility(View.GONE);
		if(LoadingView != null)
			LoadingView.setVisibility(View.VISIBLE);
		mStatus = LOADING;
	}
	
	/**
	 * 切换至加载出错状态
	 */
	public void gotoError() {
		if(mStatus == ERROR)
			return;
		if(LoadingView != null)
			LoadingView.setVisibility(View.GONE);
		if(ContentView != null)
			ContentView.setVisibility(View.INVISIBLE);
		if(BlankView != null)
			BlankView.setVisibility(View.GONE);
		if(ErrorView != null)
			ErrorView.setVisibility(View.VISIBLE);
		mStatus = ERROR;
	}
	
	/**
	 * 切换至加载成功状态
	 */
	public void gotoSuccessful() {
		if(LoadingView != null)
			LoadingView.setVisibility(View.GONE);
		if(BlankView != null)
			BlankView.setVisibility(View.GONE);
		if(ErrorView != null)
			ErrorView.setVisibility(View.GONE);
		if(ContentView != null)
			ContentView.setVisibility(View.VISIBLE);
		mStatus = SUCCESSFUL;
	}
	
	/**
	 * 加载数据
	 */
	public void onApplyLoadingData() {
		gotoLoading();
	}

	/**
	 * 获取布局文件resid
	 * @return
	 */
	protected View getLayoutView() {
		return null;
	}

	/**
	 * 获取布局文件resid
	 * @return
	 */
	protected int getLayoutResId() {
		return 0;
	}
	
	/**
	 * 获取加载中布局文件resid
	 * @return
	 */
	protected int getLoadingResId() {
		return 0;
	}
	/**
	 * 获取加载中布局文件resid
	 * @return
	 */
	protected View getLoadingView() {
		return new LoadingView(mContext);
	}
	/**
	 * 获取加载出错布局文件resid
	 * @return
	 */
	protected int getErrorResId() {
		return 0;
	}
	/**
	 * 获取加载出错布局文件resid
	 * @return
	 */
	protected View getErrorView() {
		return new ErrorView(mContext);
	}
	/**
	 * 获取加载无数据布局文件resid
	 * @return
	 */
	protected int getBlankResId() {
		return 0;
	}
	/**
	 * 获取加载无数据布局文件resid
	 * @return
	 */
	protected View getBlankView() {
		return new BlankView(mContext);
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		notifyDataSetChanged();
	}
	
	public void notifyDataSetChanged() {
		if(getAutoLoading() && (mStatus == INITIALIZED || 
				(mStatus == ERROR && getRetryOnError()))) {
			onApplyLoadingData();
		}
	}
	
	protected void runOnUiThread(Runnable action) {
		Activity activity = null;
		if (mContext instanceof Activity) {
			activity = (Activity) mContext;
		} else {
			IActivityContext context = ActivityManager.get().currentActivity();
			if (context != null) {
				activity = (Activity) context;
			}
		}
		if (activity != null) {
			activity.runOnUiThread(action);
		}
	}
	
	protected void startActivity(Class<?> cls) {
		Intent intent = new Intent(mContext, cls);
		startActivity(intent);
	}
	
	protected void startActivityForResult(Class<?> cls, int requestCode) {
		Intent intent = new Intent(mContext, cls);
		startActivityForResult(intent, requestCode);
	}
	
	public void startActivity(Intent intent) {
		mContext.startActivity(intent);
    }
	
	public void startActivityForResult(Intent intent, int requestCode) {
		Activity activity = (Activity) mContext;
		activity.startActivityForResult(intent, requestCode);
    }
}
